package com.strongbj.iot.devices.dam.sub.dacai.response.handle;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import com.strongbj.core.message.IMessageHandle;
import com.strongbj.core.util.ByteUtil;
import com.strongbj.iot.devices.dam.common.AbstractTaskDelayedRunnable;
import com.strongbj.iot.devices.dam.common.DAMManager;
import com.strongbj.iot.devices.dam.common.ITaskManager;
import com.strongbj.iot.devices.dam.message.DAMMessageFactory;
import com.strongbj.iot.devices.dam.sub.dacai.message.DaCaiMessage;
import com.strongbj.iot.devices.dam.sub.dacai.message.DaCaiMessageType;
import com.strongbj.iot.devices.dam.sub.dacai.response.entity.ScreenReturnTextControlEntity;
import com.strongbj.iot.devices.dam.sub.dacai.response.entity.ScreenReturnTextControlFactory;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandlerContext;

public class SetLocalNetParamsHandle implements IMessageHandle<DaCaiMessage, Object> {
	private static Logger logger = LogManager.getLogger(OpenNetParamsPageHandle.class.getName());
	protected final static String COMMAND_CODE = "B111"; // 打开页面命令的编号
//	protected final static String NET_PAGE_INDEX = "0004";  	// 网络设置页面的索引
	protected final static byte[] DEFAULT_DEVICE_CODE = { 00, 00, 00 }; // 设备默认编号
	protected final static byte[] EMPTY_DATAS = {}; // 空参数
	protected final static long MAX_SET_AND_WAIT_MILLISECOND = 2000; // 最大等待并设置参数的毫秒数
	protected DAMMessageFactory damMessageFactory = new DAMMessageFactory();

	private String ip, mask, gateway; // 从屏幕获取的数据
	private long prevGetTime; // 上一次获取数据的时间
	private ScreenReturnTextControlEntity screenReturnTextControlEntity;

	@Override
	public boolean isHandle(DaCaiMessage t) {
		if (t.getMessageType() == DaCaiMessageType.System && t.getCommand().equals(COMMAND_CODE)) {
			ScreenReturnTextControlEntity sr = ScreenReturnTextControlFactory.create(t.getDatas());

			// 如果控件类型为按钮，屏幕id为4，按钮id为1,2,3，就认为是打开网络界面
			if (sr.getControlType() == 0x11 && sr.getScreenId() == 4
					&& (sr.getControlId() == 1 || sr.getControlId() == 2 || sr.getControlId() == 3)) {
				this.screenReturnTextControlEntity = sr;
				return true;
			}
		}
		return false;
	}

	private void initScreenParams() {
		this.ip = "";
		this.mask = "";
		this.gateway = "";
	}

	@Override
	public Object handle(ChannelHandlerContext ctx, DaCaiMessage t) {
		if (System.currentTimeMillis() - prevGetTime > MAX_SET_AND_WAIT_MILLISECOND) {
			initScreenParams();
		}
		switch (this.screenReturnTextControlEntity.getControlId()) {
		case 1:
			this.ip = new String(ByteUtil.hexStringToBytes(this.screenReturnTextControlEntity.getContent()));
			break;
		case 2:
			this.mask = new String(ByteUtil.hexStringToBytes(this.screenReturnTextControlEntity.getContent()));
			break;
		case 3:
			this.gateway = new String(ByteUtil.hexStringToBytes(this.screenReturnTextControlEntity.getContent()));
			break;
		default:
			return null;
		}
		this.prevGetTime = System.currentTimeMillis();

		if (this.ip == "" || this.mask == "" || this.gateway == "")
			return null;

		byte[] datas = this.NetParamesEntity2Bytes(DEFAULT_DEVICE_CODE, this.ip, this.mask, this.gateway);
		
		ITaskManager taskManager = DAMManager.getTaskManager(t.getDamCode());
		taskManager.addSendTask(new AbstractTaskDelayedRunnable() {
			@Override
			protected void taskRun() {
				sendMessageToDAM(ctx.channel(), datas);
				// 网卡设置需要过多时间，顾让接收DAM的命令睡一下
				try {
					Thread.sleep(1000);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
			
		});
		initScreenParams(); // 发送后初始化屏幕
		return null;
	}

	/**
	 * 发送获取本地网络的消息
	 * 
	 * @param channel
	 */
	private void sendMessageToDAM(Channel channel, byte[] datas) {
		ByteBuf bs = Unpooled.copiedBuffer(datas);
		ChannelFuture cf = channel.writeAndFlush(bs);
		cf.addListener(new ChannelFutureListener() {

			@Override
			public void operationComplete(ChannelFuture future) throws Exception {
				if (future.isSuccess()) {
					logger.info("DAM自动下发设置本地网络参数命令成功 下发命令={}  ", ByteUtil.byteArrToHexString(datas, true));
				} else {
					logger.error("DAM自动下发设置本地网络参数命令失败 下发命令={}  ", ByteUtil.byteArrToHexString(datas, true));
				}
			}
		});
	}

	/**
	 * 网络参数对象转byte数组
	 * 
	 * @param np
	 * @return
	 */
	private byte[] NetParamesEntity2Bytes(byte[] devAddress, String ip, String mask, String gateway) {
		// 创建
		byte[] netParamsDatas = new byte[12];
		// 将ip赋值到4byte数组中
		this.setParamsToBytes(ip, netParamsDatas, 0);
		// 将子网掩码赋值到4byte数组中
		this.setParamsToBytes(mask, netParamsDatas, 4);
		// 将默认网关赋值到4byte数组中
		this.setParamsToBytes(gateway, netParamsDatas, 8);

		// 将命令发送到屏幕硬件
		byte[] datas = damMessageFactory.createDAMMessage(ByteUtil.longToBytes(System.currentTimeMillis()), devAddress, // 设备编号
				(byte) 0, // 设备类型，默认填0
				(byte) 0, // 版本号，默认填0
				(byte) 0x10, // 设置网络参数命令
				netParamsDatas // 设置的网络参数数据
		); // 通过dam消息工厂获取设置网络参数的byte命令数组
		return datas;
	}

	/**
	 * 设置指定*.*.*.*格式的数据转为4byte数组
	 * 
	 * @param srcString  源数据
	 * @param destBytes  目标数组
	 * @param destOffset 赋值的目标数组偏移量
	 */
	private void setParamsToBytes(String srcString, byte[] destBytes, int destOffset) {
		String[] strIps = srcString.split("[.]");
		for (int i = 0; i < strIps.length; i++) {
			String sNum = strIps[i].replace("\0", "").replace("\r", "").replace("\n", "");
			destBytes[i + destOffset] = Integer.valueOf(sNum, 10).byteValue();
		}
	}
}
